package br.com.sovi.gwt.client.rastreamento;

import br.com.sovi.gwt.client.entity.Ponto;
import br.com.sovi.gwt.client.entity.rastreamento.Rastreavel;
import br.com.sovi.gwt.client.rastreamento.service.RastreamentoService;
import br.com.sovi.gwt.client.rastreamento.service.RastreamentoServiceAsync;

import com.google.gwt.core.client.GWT;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.control.SmallMapControl;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.gwtext.client.core.Function;
import com.gwtext.client.widgets.Tool;
import com.gwtext.client.widgets.portal.Portlet;

public class RastreavelMapPortlet extends Portlet {

	private static int UPDATE_INTERVAL = 5000;

	private Rastreavel rastreavel;

	private static RastreamentoServiceAsync service;

	private Timer rastreadorTimer;

	private Marker marker;

	public static RastreamentoServiceAsync getService() {
		if (service == null) {
			service = (RastreamentoServiceAsync) GWT.create(RastreamentoService.class);
		}
		return service;
	}

	public RastreavelMapPortlet(Rastreavel rastreado) {
		this.setRastreavel(rastreado);
		this.setTitle(rastreado.getNome());
		this.setSize(300, 200);
		this.setCollapsible(true);

		final LatLng latLng = LatLng.newInstance(rastreado.getPoint().getLatitude(), rastreado.getPoint()
				.getLongitude());

		final MapWidget map = new MapWidget();
		map.setSize("100%", "100%");
		map.setCenter(latLng, 10);
		map.addControl(new SmallMapControl());
		marker = new Marker(latLng);
		map.addOverlay(marker);
		map.setScrollWheelZoomEnabled(true);

		this.add(map);

		this.addTool(new Tool(Tool.RESTORE, new Function() {
			@Override
			public void execute() {
				map.panTo(latLng);
			}
		}));

		new Timer() {
			@Override
			public void run() {
				map.checkResizeAndCenter();
			}
		}.schedule(1);

		rastreadorTimer = new Timer() {
			@Override
			public void run() {
				getService().getUltimoPonto(getRastreavel(), new AsyncCallback<Ponto>() {

					@Override
					public void onSuccess(Ponto result) {
						LatLng lng = LatLng.newInstance(result.getLatitude(), result.getLongitude());
						marker.setLatLng(lng);
						map.panTo(lng);
					}

					@Override
					public void onFailure(Throwable caught) {
						GWT.log(".onFailure() ", caught);
					}

				});
			}
		};

		startRastreamento();
	}

	public void startRastreamento() {
		rastreadorTimer.scheduleRepeating(UPDATE_INTERVAL);
	}

	public void stopRastreamento() {
		rastreadorTimer.cancel();
	}

	public Rastreavel getRastreavel() {
		return rastreavel;
	}

	public void setRastreavel(Rastreavel rastreado) {
		this.rastreavel = rastreado;
	}

}
